package com.map.module.lib;

import java.util.List;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMapStatusChangeListener;
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.InfoWindow.OnInfoWindowClickListener;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiCitySearchOption;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiIndoorResult;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.search.sug.OnGetSuggestionResultListener;
import com.baidu.mapapi.search.sug.SuggestionResult;
import com.baidu.mapapi.search.sug.SuggestionSearch;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity  implements OnClickListener, OnGetSuggestionResultListener,OnMapStatusChangeListener, BDLocationListener, OnGetGeoCoderResultListener{

	protected static final String TAG = "MainActivity";
	protected static final int REQUEST_OK = 0;
	private SuggestionSearch mSuggestionSearch = null;
	private BaiduMap mBaiduMap = null;
	/**
	 * 搜索关键字输入窗口
	 */
	private ArrayAdapter<String> msugAdapter = null;
	private MapView mMvMap;
	private MyLocationConfiguration.LocationMode mCurrentMode;
	private LocationClient mLocClient;
	private GeoCoder mgeoCoder;
	private String mCity;
	private boolean isFirstLoc = true;
	private LatLng mlocationLatLng;
	private EditText msearchAddress;
	private List<PoiInfo> mpoiInfos;
	private ListView mlvSearchPois;
	private Button mbtnSearch;
	private TextView mtvClose;

	private String address = "";

	private PoiSearchAdapter mpoiSearchAdapter;

	private InfoWindow mInfoWindow;
	private ImageButton mibiBackCurrent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
		SDKInitializer.initialize(getApplicationContext());
		setContentView(R.layout.activity_more_address);
		initData();
	}

	private void initData() {

		msearchAddress = (EditText) findViewById(R.id.main_search_address);
		mlvSearchPois = (ListView) findViewById(R.id.main_search_pois);
		mbtnSearch = (Button) findViewById(R.id.btn_search);
		mtvClose = (TextView) findViewById(R.id.cancle);
		mibiBackCurrent = (ImageButton) findViewById(R.id.ib_back_current);
		mbtnSearch.setOnClickListener(this);
		mtvClose.setOnClickListener(this);
		mibiBackCurrent.setOnClickListener(this);
		mlvSearchPois.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
				mlvSearchPois.setVisibility(View.GONE);
				if (mpoiInfos != null) {
					if (mpoiInfos.get(position) != null) {
						final LatLng location = mpoiInfos.get(position).location;
						if (location != null) {
							new Handler().post(new Runnable() {
								@Override
								public void run() { 
									mBaiduMap.clear();
									msearchAddress.setText(mpoiInfos.get(position).name);
									Bundle bundle = new Bundle();
									bundle.putString("selectAddress",mpoiInfos.get(position).address+mpoiInfos.get(position).name);
									setResult(RESULT_OK, getIntent().putExtras(bundle));
									//finish();
									MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(location,18);
									mBaiduMap.animateMapStatus(msu);
									mark(location.latitude,location.longitude,mpoiInfos.get(position).name,R.drawable.gps_red);
								}
							});
						}
					}
				}
			}
		});
		mMvMap = (MapView) findViewById(R.id.map);
		mBaiduMap = mMvMap.getMap();
		MapStatus mapStatus = new MapStatus.Builder().zoom(15).build();
		MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);
		mBaiduMap.setMapStatus(mMapStatusUpdate);
		// 地图状态改变相关监听
		mBaiduMap.setOnMapStatusChangeListener(this);
		// 开启定位图层
		mBaiduMap.setMyLocationEnabled(true);
		// 定位图层显示方式
		mCurrentMode = MyLocationConfiguration.LocationMode.NORMAL;
		mBaiduMap.setMyLocationConfigeration(new MyLocationConfiguration(mCurrentMode, true, null));
		mLocClient = new LocationClient(this);
		// 注册定位监听
		mLocClient.registerLocationListener(this);
		// 定位选项
		LocationClientOption option = new LocationClientOption();
		/**
		 * coorType - 取值有3个： 返回国测局经纬度坐标系：gcj02 返回百度墨卡托坐标系 ：bd09 返回百度经纬度坐标系
		 * ：bd09ll
		 */
		option.setCoorType("bd09ll");
		// 设置是否需要地址信息，默认为无地址
		option.setIsNeedAddress(true);
		// 设置是否需要返回位置语义化信息，可以在BDLocation.getLocationDescribe()中得到数据，ex:"在天安门附近"，
		// 可以用作地址信息的补充
		option.setIsNeedLocationDescribe(true);
		// 设置是否需要返回位置POI信息，可以在BDLocation.getPoiList()中得到数据
		option.setIsNeedLocationPoiList(true);
		/**
		 * 设置定位模式 Battery_Saving 低功耗模式 Device_Sensors 仅设备(Gps)模式 Hight_Accuracy
		 * 高精度模式
		 */
		option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
		// 设置是否打开gps进行定位
		option.setOpenGps(true);
		// 设置扫描间隔，单位是毫秒 当<1000(1s)时，定时定位无效
		option.setScanSpan(1000);
		// 设置 LocationClientOption
		mLocClient.setLocOption(option);
		// 开始定位
		mLocClient.start();

		msearchAddress.setText(getIntent().getStringExtra("addrStr"));

		mBaiduMap.setOnMapClickListener(new OnMapClickListener() {

			@Override
			public boolean onMapPoiClick(MapPoi arg0) {
				// TODO Auto-generated method stub
				return false;
			}

			// 此方法就是点击地图监听
			@Override
			public void onMapClick(LatLng latLng) {
				// 获取经纬度
				double latitude = latLng.latitude;
				double longitude = latLng.longitude;
				System.out.println("latitude=" + latitude + ",longitude=" + longitude);
				// 先清除图层
				mBaiduMap.clear();
				// 实例化一个地理编码查询对象
				GeoCoder geoCoder = GeoCoder.newInstance();
				// 设置反地理编码位置坐标
				ReverseGeoCodeOption op = new ReverseGeoCodeOption();
				op.location(latLng);

				// 发起反地理编码请求(经纬度->地址信息)
				geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {

					@Override
					public void onGetReverseGeoCodeResult(ReverseGeoCodeResult poiResult) {
						mBaiduMap.clear();
						// 获取点击的坐标地址
						address = poiResult.getAddress();
						mpoiInfos = poiResult.getPoiList();
						msearchAddress.setText(address);
						mlvSearchPois.setVisibility(View.VISIBLE);
						if(mpoiInfos == null)return;
						for (int i = 0; i < mpoiInfos.size(); i++) {
							mark(mpoiInfos.get(i).location.latitude, mpoiInfos.get(i).location.longitude,
									mpoiInfos.get(i).name, R.drawable.gps_blue);
						}
						mpoiSearchAdapter.update(mpoiInfos);
						mBaiduMap.hideInfoWindow();
						mark(poiResult.getLocation().latitude, poiResult.getLocation().longitude,poiResult.getAddress(), R.drawable.gps_red);
					}

					@Override
					public void onGetGeoCodeResult(GeoCodeResult arg0) {
					}
				});
				geoCoder.reverseGeoCode(op);
			}
		});

		mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() { // 点击覆盖物事件

			@Override
			public boolean onMarkerClick(Marker arg0) {
				showLocation(arg0);
				return false;
			}
		});
		mpoiSearchAdapter = new PoiSearchAdapter(MainActivity.this);
		mlvSearchPois.setAdapter(mpoiSearchAdapter);
	}

	/*
	 * 接受周边地理位置结果
	 * 
	 * @param poiResult
	 */
	@Override
	protected void onDestroy() {
		super.onDestroy();
		mBaiduMap.setMyLocationEnabled(false);
		mMvMap.onDestroy();
		if (mgeoCoder != null) {
			mgeoCoder.destroy();
		}
		mMvMap = null;
		if (mSuggestionSearch != null) {
			mSuggestionSearch.destroy();
			mSuggestionSearch = null;
		}

	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_search:
			InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
			if (imm != null) {
				imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
			}
			// 创建PoiSearch实例
			PoiSearch poiSearch = PoiSearch.newInstance();
			// 城市内检索
			PoiCitySearchOption poiCitySearchOption = new PoiCitySearchOption();
			// 关键字
			poiCitySearchOption.keyword(msearchAddress.getText().toString());
			// 城市
			poiCitySearchOption.city(mCity);
			// 设置每页容量，默认为每页10条
			poiCitySearchOption.pageCapacity(5);
			// 分页编号
			poiCitySearchOption.pageNum(3);
			// 设置poi检索监听者
			poiSearch.setOnGetPoiSearchResultListener(OnGetPoiSearchResultListener);
			poiSearch.searchInCity(poiCitySearchOption);
			poiSearch.destroy();
			break;
		case R.id.cancle:
			finish();
			break;
		case R.id.ib_back_current:
			mlvSearchPois.setVisibility(View.GONE);
			isFirstLoc = true;
			mLocClient.restart();
			break;
		default:
			break;
		}
	}

	@Override
	public void onResume() {
		super.onResume();
		mMvMap.onResume();
	}

	@Override
	public void onPause() {
		super.onPause();
		mMvMap.onPause();
	}

	@Override
	public void onGetSuggestionResult(SuggestionResult res) {
		if (res == null || res.getAllSuggestions() == null) {
			return;
		}
		msugAdapter.clear();
		for (SuggestionResult.SuggestionInfo info : res.getAllSuggestions()) {
			if (info.key != null)
				msugAdapter.add(info.key + " " + info.city + info.district);
		}
		msugAdapter.notifyDataSetChanged();
	}

	OnGetPoiSearchResultListener OnGetPoiSearchResultListener = new OnGetPoiSearchResultListener() {
		// poi 查询结果回调
		@Override
		public void onGetPoiResult(PoiResult poiResult) {
			mBaiduMap.clear();
			mpoiInfos = poiResult.getAllPoi();
			if (mpoiInfos != null) {
				mlvSearchPois.setVisibility(View.VISIBLE);
				mpoiSearchAdapter.update(mpoiInfos);
				new Handler().post(new Runnable() {
					@Override
					public void run() {
						for (int i = 0; i < mpoiInfos.size(); i++) {
							mark(mpoiInfos.get(i).location.latitude, mpoiInfos.get(i).location.longitude, mpoiInfos.get(i).name,R.drawable.gps_blue);
						}
						if (mpoiInfos.size() > 0) {
							MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(mpoiInfos.get(0).location, 14);
							mBaiduMap.animateMapStatus(msu);
						}
					}
				});
			}
		}

		// poi 详情查询结果回调
		@Override
		public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
			Log.d("poiDetailResult", poiDetailResult.toString());
		}

		@Override
		public void onGetPoiIndoorResult(PoiIndoorResult poiDetailResult) {
			// TODO Auto-generated method stub
			Log.d("poiDetailResult", poiDetailResult.toString());
		}

	};

	@Override
	public void onMapStatusChange(MapStatus mapStatus) {

	}

	@Override
	public void onMapStatusChangeFinish(MapStatus mapStatus) {
		// 地图操作的中心点
		LatLng cenpt = mapStatus.target;

		mgeoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(cenpt));

	}

	@Override
	public void onMapStatusChangeStart(MapStatus mapStatus) {

	}

	@Override
	public void onReceiveLocation(BDLocation bdLocation) {
		// 如果bdLocation为空或mapView销毁后不再处理新数据接收的位置
		if (bdLocation == null || mBaiduMap == null) {
			return;
		}

		// 定位数据
		mBaiduMap.clear();
		MyLocationData data = new MyLocationData.Builder()
				// 定位精度bdLocation.getRadius()
				.accuracy(bdLocation.getRadius())
				// 此处设置开发者获取到的方向信息，顺时针0-360
				.direction(bdLocation.getDirection())
				// 经度
				.latitude(bdLocation.getLatitude())
				// 纬度
				.longitude(bdLocation.getLongitude())
				// 构建
				.build();

		// 设置定位数据
		mBaiduMap.setMyLocationData(data);

		// 是否是第一次定位
		if (isFirstLoc) {
			isFirstLoc = false;
			LatLng ll = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
			MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(ll, 18);
			mBaiduMap.animateMapStatus(msu);
		}

		mlocationLatLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
		// 获取城市，待会用于POISearch
		mCity = bdLocation.getCity();

		// 创建GeoCoder实例对象
		mgeoCoder = GeoCoder.newInstance();
		// 发起反地理编码请求(经纬度->地址信息)
		ReverseGeoCodeOption reverseGeoCodeOption = new ReverseGeoCodeOption();
		// 设置反地理编码位置坐标
		reverseGeoCodeOption.location(new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude()));
		mgeoCoder.reverseGeoCode(reverseGeoCodeOption);

		// 设置查询结果监听者
		mgeoCoder.setOnGetGeoCodeResultListener(this);
		mark(mlocationLatLng.latitude, mlocationLatLng.longitude, bdLocation.getAddrStr(), R.drawable.gps_red);
	}

	@Override
	public void onGetGeoCodeResult(GeoCodeResult arg0) {

	}

	// 拿到变化地点后的附近地址
	@Override
	public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
		mLocClient.stop();
		final List<PoiInfo> poiInfos = reverseGeoCodeResult.getPoiList();
		Log.i(TAG, "这里的值:" + poiInfos);
		if (poiInfos != null && !"".equals(poiInfos)) {
		}
	}

	/** 
	 * 显示气泡
	 * 
	 * @param marker
	 */
	private void showLocation(final Marker marker) {
		// 创建InfoWindow展示的view
		LatLng pt = null;
		double latitude, longitude;
		latitude = marker.getPosition().latitude;
		longitude = marker.getPosition().longitude;

		View view = LayoutInflater.from(this).inflate(R.layout.map_item, null); // 自定义气泡形状
		TextView textView = (TextView) view.findViewById(R.id.my_postion);
		pt = new LatLng(latitude, longitude);
		textView.setText(marker.getTitle());

		// 定义用于显示该InfoWindow的坐标点
		// 创建InfoWindow的点击事件监听者
		OnInfoWindowClickListener listener = new OnInfoWindowClickListener() {
			@Override
			public void onInfoWindowClick() {
				mBaiduMap.hideInfoWindow();// 影藏气泡
			}
		};
		// 创建InfoWindow
		mInfoWindow = new InfoWindow(BitmapDescriptorFactory.fromView(view), pt, 0, listener);

		mBaiduMap.showInfoWindow(mInfoWindow); // 显示气泡
	}

	private void mark(double latitude, double longitude, String title, int picId) {
		// 显示覆盖物
		// 定义Maker坐标点
		LatLng point = new LatLng(latitude, longitude);
		// 构建Marker图标
		BitmapDescriptor mbitmap = BitmapDescriptorFactory.fromResource(picId);
		// 构建MarkerOption，用于在地图上添加Marker
		OverlayOptions option = new MarkerOptions().position(point).icon(mbitmap);
		// 在地图上添加Marker，并显示
		Marker marker = (Marker) mBaiduMap.addOverlay(option);
		marker.setTitle(title);  
		Bundle bundle = new Bundle();
		bundle.putSerializable("recore", "ddd");
		marker.setExtraInfo(bundle);
	}

	@Override
	public void onMapStatusChangeStart(MapStatus arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}

}
